#!/usr/bin/env python

# scenesel.py
# This file is part of landmerge, (c) Matus Tejiscak 2008
# Released under GNU GPLv3 (http://www.gnu.org/licenses/gpl.html)

import string
import sys
import os
import getopt
import math

from scenesel import UTMArea, coincidentScenes
from planner import createPlan, Step
from downloader import downloadScenes, gunzipScenes
from stitcher import stitch
from utm import LatLonToUTMXY
from parseglovis import parseGlovis

# A general exception.
class LandmergeError(RuntimeError):
	def foo(self):
		pass

# Print usage
def usage():
	print "Usage:"
	print "  landmerge -z <UTM_zone> -a <area> [-q <quality>] [-o <outfile>]"
	print "  landmerge -f <glovis_spec_file> [-q <quality>] [-o <outfile>]"
	print ""
	print "Basic options:"
	print "  Area definition:"
	print "    -a WIDTHxHEIGHT@EASTING,NORTHING  (e.g. 1000x1000@500000,400000)"
	print "       Easting, northing specifies the position of the top-left"
	print "       corner of the image."
	print "    -A WIDTHxHEIGHT@EASTING,NORTHING"
	print "       The same, except that the @X,Y part is the *center* of the image."
	print "  Glovis:"
	print "    -f Use a Glovis file instead of the manual area specification."
	print "  Zone number:"
	print "    -z ZONE  (zone number in range 1..60)"
	print "  Output file:"
	print "    -o FILENAME  (format specified by the extension)"
	print "       Available formats: *.jpg, *.png, *.raw"
	print "  Output quality (*.jpg only):"
	print "    -q QUALITY  (number 1..100, 1 = worst, 100 = finest)"
	print ""
	print "Additional options:"
	print "  Parallelization:"
	print "    -t N  (how many merge processes to run in parallel)"
	print "  Old merge:"
	print "    -O    (use the old merge program, giving fancier albeit unrealistic images)"
	print "  Panchro postprocess mix:"
	print "    -p q  (q \in <0, 1>. default 0. How intensively to mix the panchro chan"
	print "           into the processed image; it's an ad-hoc beautification.)"
	print "  Overcrop:"
	print "    -c N  (overcrop the scene quadrilateral by this many pixels (along"
	print "           each side)). A workaround for visible seams. Default: 2."
	print "  Units:"
	print "    -u UNITS"
	print "    --units UNITS  (one of: m, km, deg)"
	print "           m-utm:  Everything in meters (UTM)               [DEFAULT]"
	print "           km-utm: Everything in kilometers (UTM)"
	print "           m-deg:  Dimensions in m, angular (@latitude,longitude) position"
	print "           km-deg: Dimensions in km, angular (@latitude,longitude) position"

def main(argv):
	print "This is landmerge, hello."
	
	version = string.split(string.split(sys.version)[0], ".")
	if map(int, version) < [2, 4]:
		print "Landmerge needs Python >= 2.4."
		sys.exit(1)
	
	outfile = "outfile.png"
	units = 'm-utm'
	quality = 75
	psi = 0.0
	overcrop = 2
	old_merge = False
	area = UTMArea()
	threadCount = 2
	centered = False
	scenelist = None
	try:
		opts, args = getopt.getopt(argv, "Oha:z:o:q:p:t:c:A:u:f:", ["help", "area=", "zone=", "units=", "scenelist="])
		for opt, arg in opts:
			if opt in ('-u', '--units'):
				units = arg
			if opt in ('-O',):
				old_merge = True
			if opt in ('-p',):
				psi = float(arg)
			if opt in ('-t',):
				threadCount = int(arg)
			if opt in ('-q',):
				quality = int(arg)
			if opt in ('-o',):
				outfile = arg
			if opt in ('-c',):
				overcrop = int(arg)
			if opt in ('-z', '--zone'):
				area.zone = int(arg)
			if opt in ('-A',):
				area.parseFrom(arg)
				centered = True
			if opt in ('-a', '--area'):
				area.parseFrom(arg)
				centered = False
			if opt in ('-f', '--scenelist'):
				scenelist = arg
			if opt in ('-h', '--help'):
				usage()
				sys.exit(1)
	except getopt.GetoptError:
		usage()
		sys.exit(2)
  
	if scenelist:
		scenes = parseGlovis(scenelist)
	else:
		if area.y is None:
			print "No area given."
			usage()
			sys.exit(1)
		
		if units not in ('m-utm', 'km-utm', 'm-deg', 'km-deg'):
			print "Invalid units specified (-u). See --help for more information."
			sys.exit(1)
		
		if units not in ('m-deg', 'km-deg') and area.zone is None:
			print "UTM zone not specified!"
			print "See --help for more info."
			sys.exit(1)
		
		if units in ('m-deg', 'km-deg'):
			zoneGiven = area.zone is not None
			(area.x, area.y, area.zone) = LatLonToUTMXY(area.x, area.y, area.zone)
			if zoneGiven:
				print "Using suggested UTM zone %d." % area.zone
			else:
				print "No zone given, guessing %d." % area.zone
		
		if units == 'km-deg':
			area.w, area.h = map(lambda x: 1000*x, (area.w, area.h))
		if units == 'km-utm':
			area.x, area.y, area.w, area.h = map(lambda x: 1000*x, (area.x, area.y, area.w, area.h))
		
		if centered:
			area.x = area.x - area.w / 2;
			area.y = area.y + area.w / 2;
		
		if (not os.path.isfile("bin/merge")) or (not os.path.isfile("bin/stitch")):
			print "Native utils not built, building src/..."
			if os.system("make -C src"):
				print "Could not make in src/!"
				sys.exit(1)
		
		print "UTM area: %s" % area.show()
		sys.stdout.write("Calculating coincident scenes...\r")
		scenes = coincidentScenes(area)
		sys.stdout.write("                                \r")
		print "Coincident scenes:"
		for path, row in scenes:
			print "  (p%d, r%d)" % (path, row)
		
	if len(scenes) == 0:
		print "No scenes to process. Exiting."
		sys.exit(0)
		
	print "Okay, let's download the scenes."
	status = downloadScenes(scenes)
	
	print "Gunzipping..."
	scenes = [scene for scene, succeeded in status if succeeded]
	if len(scenes) == 0:
		print "No scenes downloaded successfully. Exiting."
		sys.exit(0)
	gunzipScenes(scenes)
	
	print "Creating plan..."
	(width, height, plan) = createPlan(area, scenes, overcrop)
	print "The plan goes as follows:"
	print "  Create an image %d x %d pixels" % (width, height)
	for step in plan:
		print "  %s" % step.show()
	
	print "Stitching..."
	stitch(area, width, height, plan, outfile, quality, psi, old_merge, threadCount)

main(sys.argv[1:])
